package com.ksl.kinglockguard.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.http.util.EncodingUtils;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.os.Environment;
import android.os.StatFs;
import android.util.DisplayMetrics;

import com.ksl.kinglockguard.data.Constants;


/**
 * 文件帮助类
 * 
 * @author kinsgame
 */
public class SdcardFileUtil {
	private static final int BYTE_BUFFER_SIZE = 256;
	
	static{
		File root = new File(Constants.FOLDER_ROOT);
		if(!root.exists())
			root.mkdirs();
	}

	/**
	 * 是否存储卡状态
	 * 
	 * @return 有存储卡则返回true，否则返回false
	 */
	public static boolean haveSDCard() {
		return android.os.Environment.getExternalStorageState().equals(
				android.os.Environment.MEDIA_MOUNTED);
	}
	
	public static String getRootFilePath() {
		if (haveSDCard()) {
			return Environment.getExternalStorageDirectory().getAbsolutePath() + "/";// filePath:/sdcard/
		} else {
			return Environment.getDataDirectory().getAbsolutePath() + "/data/"; // filePath: /data/data/
		}
	}
	
	public static String getUpdatePath(){
		File root = new File(Constants.FOLDER_ROOT);
		if(!root.exists())
			root.mkdirs();
		
		File update=new File(Constants.FOLDER_UPDATE);
		if(!update.exists()){
			update.exists();
		}
		return update.getAbsolutePath();
	}
	public static String getErrorPath(){
		File root = new File(Constants.FOLDER_ROOT);
		if(!root.exists())
			root.mkdirs();
		
		File update=new File(Constants.FOLDER_ERROR);
		if(!update.exists()){
			update.mkdirs();
		}
		return update.getAbsolutePath();
	}
	
	public static String getUpdateAppPath(){
		File root = new File(Constants.PRIVATE_UPDATE);
		if(!root.exists())
			root.mkdirs();
		
		return root.getAbsolutePath();
		
	}

	/**
	 * 得到图片保存路径
	 * 
	 * @return 返回图片保存的路径
	 */
	public static String getIconPath() {
		String iconPath = null;
		File sdcardPath = android.os.Environment.getExternalStorageDirectory();// sdcard
		iconPath = sdcardPath.getPath() + Constants.FOLDER_ICONS;
		File iconPathFile = new File(iconPath);
		if (!iconPathFile.exists()) {
			iconPathFile.mkdirs();
		} else {
		}
		return iconPath;
	}

	/**
	 * 得到图片保存路径
	 * 
	 * @return 返回图片保存的路径
	 */
	public static String getUserIconPath() {
		String iconPath = null;
		File sdcardPath = android.os.Environment.getExternalStorageDirectory();// sdcard
		iconPath = sdcardPath.getPath() + Constants.FOLDER_USERICONS;
		File iconPathFile = new File(iconPath);
		if (!iconPathFile.exists()) {
			iconPathFile.mkdirs();
		} else {
		}
		return iconPath;
	}

	/**
	 * 将字节数组保存为.png格式文件
	 * 
	 * @param buffer
	 *            字节数组
	 * @param fileName
	 *            文件名
	 * @return 字节数组保存成功则返回true，否则返回false
	 */
	public static boolean saveBytesToFile(byte[] buffer, String fileName) {
		if (fileName == null) {
			return false;
		}
		if (!haveSDCard())
			return false;
		File file = new File(getIconPath() + fileName + ".png");
		if (file.exists())
			file.delete();
		try {
			file.createNewFile();
			FileOutputStream fos = new FileOutputStream(file, true);
			fos.write(buffer);
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 从.png格式文件中得到字节数组
	 * 
	 * @param fileName
	 *            图片文件 .png格式
	 * @return 返回文件字节数组
	 */
	public static byte[] getBytesFromFile(String fileName) {
		if (fileName == null)
			return null;
		if (!haveSDCard())
			return null;
		File file = new File(getIconPath() + fileName + ".png");
		if (!file.exists())
			return null;
		FileInputStream fis;
		byte[] buffer;
		try {
			fis = new FileInputStream(file);
			buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();
		} catch (Exception e) {
			e.printStackTrace();
			buffer = null;
		}
		return buffer;
	}

	/**
	 * 将字节数组保存为.png格式文件
	 * 
	 * @param buffer
	 *            字节数组
	 * @param fileName
	 *            文件名
	 * @return 字节数组保存成功则返回true，否则返回false
	 */
	public static boolean saveUserBytesToFile(byte[] buffer, String fileName) {
		if (fileName == null) {
			return false;
		}
		if (!haveSDCard())
			return false;
		File file = new File(getUserIconPath() + fileName + ".png");
		if (file.exists())
			file.delete();
		try {
			file.createNewFile();
			FileOutputStream fos = new FileOutputStream(file, true);
			fos.write(buffer);
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 从.png格式文件中得到字节数组
	 * 
	 * @param fileName
	 *            图片文件 .png格式
	 * @return 返回文件字节数组
	 */
	public static byte[] getUserBytesFromFile(String fileName) {
		if (fileName == null)
			return null;
		if (!haveSDCard())
			return null;
		File file = new File(getUserIconPath() + fileName + ".png");
		if (!file.exists())
			return null;
		FileInputStream fis;
		byte[] buffer;
		try {
			fis = new FileInputStream(file);
			buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();
		} catch (Exception e) {
			e.printStackTrace();
			buffer = null;
		}
		return buffer;
	}

	/**
	 * 删除文件协议
	 * 
	 * @param fileName
	 *            协议名
	 * @return 删除成功则返回true，否则返回false
	 */
	public static boolean deleteUserIconFromFile(String fileName) {
		if (fileName == null)
			return false;
		if (!haveSDCard())
			return false;
		File file = new File(getUserIconPath() + fileName + ".png");
		return file.delete();
	}

	/**
	 * 得到协议保存路径
	 * 
	 * @return 协议保存路径
	 */
	private static String getProtocolPath() {
		String protocolPath = null;
		File sdcardPath = android.os.Environment.getExternalStorageDirectory();// sdcard
		protocolPath = sdcardPath.getPath() + Constants.FOLDER_PROTOCEL;
		File protocolPathFile = new File(protocolPath);
		if (!protocolPathFile.exists()) {
			protocolPathFile.mkdirs();
		} else {
		}
		return protocolPath;
	}

	/**
	 * 将协议保存为xml文件
	 * 
	 * @param buffer
	 *            协议字节数组
	 * @param fileName
	 *            协议名称
	 * @return 协议保存成功则返回true，否则返回false
	 */
	public static boolean saveProtocelToFile(byte[] buffer, String fileName) {
		if (!haveSDCard())
			return false;
		File file = new File(getProtocolPath() + fileName + ".xml");
		if (file.exists())
			file.delete();
		try {
			file.createNewFile();
			FileOutputStream fos = new FileOutputStream(file, true);
			fos.write(buffer);
			fos.close();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 获取协议字节数组
	 * 
	 * @param fileName
	 *            协议名
	 * @return 返回协议字节数组
	 */
	public static byte[] getProtocolFromFile(String fileName) {
		if (fileName == null)
			return null;
		if (!haveSDCard())
			return null;
		File file = new File(getProtocolPath() + fileName + ".xml");
		if (!file.exists())
			return null;
		FileInputStream fis;
		byte[] buffer;
		try {
			fis = new FileInputStream(file);
			buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();
		} catch (Exception e) {
			e.printStackTrace();
			buffer = null;
		}
		return buffer;
	}

	/**
	 * 删除文件协议
	 * 
	 * @param fileName
	 *            协议名
	 * @return 删除成功则返回true，否则返回false
	 */
	public static boolean deleteProtocolFromFile(String fileName) {
		if (fileName == null)
			return false;
		if (!haveSDCard())
			return false;
		File file = new File(getProtocolPath() + fileName + ".xml");
		return file.delete();
	}

	public static boolean isApkValid(Context ctx, String apkPath) {
		File apkFile = new File(apkPath);
		if (!apkFile.exists()) {
			return false;
		}
		String PATH_PackageParser = "android.content.pm.PackageParser";
		String PATH_AssetManager = "android.content.res.AssetManager";
		try {
			Class<?> pkgParserCls = Class.forName(PATH_PackageParser);
			Class<?>[] typeArgs = { String.class };
			Constructor<?> pkgParserCt = pkgParserCls.getConstructor(typeArgs);
			Object[] valueArgs = { apkPath };
			Object pkgParser = pkgParserCt.newInstance(valueArgs);

			DisplayMetrics metrics = new DisplayMetrics();
			metrics.setToDefaults();
			typeArgs = new Class<?>[] { File.class, String.class,
					DisplayMetrics.class, int.class };
			Method pkgParser_parsePackageMtd = pkgParserCls.getDeclaredMethod(
					"parsePackage", typeArgs);

			valueArgs = new Object[] { new File(apkPath), apkPath, metrics, 0 };
			Object pkgParserPkg = pkgParser_parsePackageMtd.invoke(pkgParser,
					valueArgs);
			if (pkgParserPkg == null) {
				return false;
			}
			Field appInfoFld = pkgParserPkg.getClass().getDeclaredField(
					"applicationInfo");
			if (appInfoFld.get(pkgParserPkg) == null) {
				return false;
			}
			ApplicationInfo info = (ApplicationInfo) appInfoFld
					.get(pkgParserPkg);

			Class<?> assetMagCls = Class.forName(PATH_AssetManager);
			Object assetMag = assetMagCls.newInstance();
			typeArgs = new Class[1];
			typeArgs[0] = String.class;
			Method assetMag_addAssetPathMtd = assetMagCls.getDeclaredMethod(
					"addAssetPath", typeArgs);
			valueArgs = new Object[1];
			valueArgs[0] = apkPath;
			assetMag_addAssetPathMtd.invoke(assetMag, valueArgs);

			Resources res = ctx.getResources();
			typeArgs = new Class[3];
			typeArgs[0] = assetMag.getClass();
			typeArgs[1] = res.getDisplayMetrics().getClass();
			typeArgs[2] = res.getConfiguration().getClass();
			Constructor<Resources> resCt = Resources.class
					.getConstructor(typeArgs);
			valueArgs = new Object[3];
			valueArgs[0] = assetMag;
			valueArgs[1] = res.getDisplayMetrics();
			valueArgs[2] = res.getConfiguration();
			res = (Resources) resCt.newInstance(valueArgs);

			if (info == null) {
				return false;
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	public static String getDownloadPath() {
		String downloadPath = null;
		File sdcardPath = android.os.Environment.getExternalStorageDirectory();// sdcard
		downloadPath = sdcardPath.getPath() + Constants.FOLDER_PROTOCEL;
		File downloadPathFile = new File(downloadPath);
		if (!downloadPathFile.exists()) {
			downloadPathFile.mkdirs();
		} else {
		}
		return downloadPath;
	}

	// 复制文件
	public static void copyFile(InputStream is, File targetFile)
			throws IOException {
		BufferedInputStream inBuff = null;
		BufferedOutputStream outBuff = null;
		try {
			// 新建文件输入流并对它进行缓冲
			inBuff = new BufferedInputStream(is);
			if (targetFile.exists()) {
				targetFile.delete();
			}
			targetFile.createNewFile();
			// 新建文件输出流并对它进行缓冲
			outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));

			// 缓冲数组
			byte[] b = new byte[1024];
			int len;
			while ((len = inBuff.read(b)) != -1) {
				outBuff.write(b, 0, len);
			}
			// 刷新此缓冲的输出流
			outBuff.flush();
		} finally {
			// 关闭流
			if (inBuff != null)
				inBuff.close();
			if (outBuff != null)
				outBuff.close();
		}
	}


	/**
	 * 从网络上获得图片
	 */
	public static byte[] getImage(String path) throws Exception {
		URL url = new URL(path);
		HttpURLConnection httpURLconnection = (HttpURLConnection) url
				.openConnection();
		httpURLconnection.setRequestMethod("GET");
		httpURLconnection.setReadTimeout(6 * 1000);
		httpURLconnection.setConnectTimeout(6 * 1000);
		InputStream in = null;
		if (httpURLconnection.getResponseCode() == 200) {
			in = httpURLconnection.getInputStream();
			byte[] result = readStream(in);
			in.close();
			return result;

		}
		return null;
	}

	private static byte[] readStream(InputStream in) throws Exception {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = in.read(buffer)) != -1) {
			outputStream.write(buffer, 0, len);
		}
		outputStream.close();
		in.close();
		return outputStream.toByteArray();
	}

	public static String getProcessName(int pid) {
		String processName = null;
		try {
			if (processName == null) {
				processName = SdcardFileUtil.readFile("/proc/" + pid + "/cmdline",
						'\0');
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return processName;
	}

	public static byte[] readFile(File file) {
		ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(
				BYTE_BUFFER_SIZE);
		byte[] buffer = new byte[BYTE_BUFFER_SIZE];
		FileInputStream is = null;
		try {
			is = new FileInputStream(file);
			int len = -1;
			while ((len = is.read(buffer)) > 0) {
				byteBuffer.write(buffer, 0, len);
			}
			is.close();
		} catch (Exception e) {
			return null;
		}
		return byteBuffer.toByteArray();
	}
	
	public static byte[] readFile(String file) {
		ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(
				BYTE_BUFFER_SIZE);
		byte[] buffer = new byte[BYTE_BUFFER_SIZE];
		FileInputStream is = null;
		try {
			is = new FileInputStream(file);
			int len = -1;
			while ((len = is.read(buffer)) > 0) {
				byteBuffer.write(buffer, 0, len);
			}
			is.close();
		} catch (Exception e) {
			return null;
		}
		return byteBuffer.toByteArray();
	}

	public static String readFile(String file, char endBit) {
		byte[] b = readFile(file);
		if (b == null) {
			return null;
		}
		for (int i = 0; i < b.length; i++) {
			if (endBit == b[i]) {
				return new String(b, 0, i);
			}
		}
		return new String(b);
	}
	
	/**
	 * 获取sdcard可用空间大小
	 * 
	 * @return
	 */
	public static long getSDCardAvailableSpace() {
		StatFs statFs = new StatFs(Environment.getExternalStorageDirectory().toString());
		// 获取block的SIZE
		long blocSize = statFs.getBlockSize();
		// 己使用的Block的数量
		long availaBlock = statFs.getAvailableBlocks();
		return (availaBlock * blocSize);
	}
	
//	 /** 
//     * 一、私有文件夹下的文件存取（/data/data/包名/files） 
//     *  
//     * @param fileName 
//     * @param message 
//     */  
//    public void writeFileData(String fileName, String message) {  
//        try {  
//            FileOutputStream fout = openFileOutput(fileName, Context.MODE_PRIVATE);  
//            byte[] bytes = message.getBytes();  
//            fout.write(bytes);  
//            fout.close();  
//        } catch (Exception e) {  
//            e.printStackTrace();  
//        }  
//    }  
//  
//    /** 
//     * //读文件在./data/data/包名/files/下面 
//     *  
//     * @param fileName 
//     * @return 
//     */  
//    public String readFileData(String fileName) {  
//        String res = "";  
//        try {  
//            FileInputStream fin = openFileInput(fileName);  
//            int length = fin.available();  
//            byte[] buffer = new byte[length];  
//            fin.read(buffer);  
//            res = EncodingUtils.getString(buffer, "UTF-8");  
//            fin.close();  
//        } catch (Exception e) {  
//            e.printStackTrace();  
//        }  
//        return res;  
//    }  
    
    
    /** 
     * 写， 读sdcard目录上的文件，要用FileOutputStream， 不能用openFileOutput 
     * 不同点：openFileOutput是在raw里编译过的，FileOutputStream是任何文件都可以 
     * @param fileName 
     * @param message 
     */  
    // 写在/mnt/sdcard/目录下面的文件  
    public static void writeFileSdcard(String fileName, String message) {  
        try {  
            // FileOutputStream fout = openFileOutput(fileName, MODE_PRIVATE);  
            FileOutputStream fout = new FileOutputStream(fileName);  
            byte[] bytes = message.getBytes();  
            fout.write(bytes);  
            fout.close();  
        }  
        catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
    // 读在/mnt/sdcard/目录下面的文件  
  
    public static String readFileSdcard(String fileName) {  
        String res = "";  
        try {  
            FileInputStream fin = new FileInputStream(fileName);  
            int length = fin.available();  
            byte[] buffer = new byte[length];  
            fin.read(buffer);  
            res = EncodingUtils.getString(buffer, "UTF-8");  
            fin.close();  
        }  
        catch (Exception e) {  
            e.printStackTrace();  
        }  
        return res;  
    }  
    
    

	/***下载图片的类型***/
	public static final int LOCK_ITEM_PICTURE = 0;
	public static final int LOCK_SCREEN_PICTURE = 1; 
	public static final int LOCK_BANNER_PICTURE = 2;
	public static final int LOCK_DESK_ICON = 3;
	public static final int LOCK_BLUR_PICTURE = 4;
	public static final int LOCK_H5_PICTURE = 5;
	public static final int LOCK_PUSH_PICTURE = 6;
	public static final int LOCK_SHORT_CUT = 7;
	
	//根据图片的不同类型，存放到SD卡的不同位置
	public static File getFile(int type,String url)throws Exception{
		File f = null;
		if(type == LOCK_ITEM_PICTURE)
			f = getSmallPicFile(url);
		else if(type == LOCK_BANNER_PICTURE)
			f = getMiddlePicFile(url);
		else if(type == LOCK_SCREEN_PICTURE)
			f = getLargePicFile(url);
		else if(type == LOCK_DESK_ICON)
			f = getDeskIconFile(url);
		else if(type == LOCK_BLUR_PICTURE)
			f = getLargePicBlurFile(url);
		else if(type == LOCK_H5_PICTURE)
			f = getH5PicFile(url);
		else if(type == LOCK_PUSH_PICTURE)
			f = getPushPicFile(url);
		else if(type == LOCK_SHORT_CUT)
			f = getShortcutFile(url);
		else
			throw new NullPointerException("file does not exist ");
		return f;
	}
		
	public static File getSmallPicFile(String url) {
		String filename = String.valueOf(url.hashCode());
		File f = new File(Constants.FOLDER_ICONS + filename);
		return f;
	}
	
	public static File getMiddlePicFile(String url) {
		String filename = String.valueOf(url.hashCode());
		File f = new File(Constants.FOLDER_BANNERPIC + filename);
		return f;
	}
	public static File getLargePicFile(String url) {
		String filename = String.valueOf(url.hashCode());
		File f = new File(Constants.FOLDER_PICTURE + filename);
		return f;
	}
	public static File getDeskIconFile(String url) {
		String filename = String.valueOf(url.hashCode());
		File f = new File(Constants.FOLDER_DESKICON + filename);
		return f;
	}
	public static File getLargePicBlurFile(String url) {
		String filename = String.valueOf(url.hashCode());
		File f = new File(Constants.FOLDER_PICTURE + filename+".blur");
		return f;
	}
	public static File getH5PicFile(String url) {
		String filename = String.valueOf(url.hashCode());
		File f = new File(Constants.FOLDER_H5PIC + filename);
		return f;
	}
	public static File getPushPicFile(String url) {
		String filename = String.valueOf(url.hashCode());
		File f = new File(Constants.FOLDER_PUSHPIC + filename);
		return f;
	}
	public static File getShortcutFile(String url) {
		String filename = String.valueOf(url.hashCode());
		File f = new File(Constants.FOLDER_SHORTCUT + filename);
		return f;
	}
}
